package com.doubao.auth.util;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * 微信数据解密工具
 */
@Slf4j
public class WxBizDataCrypt {
    private final String appId;
    private final String sessionKey;
    private final ObjectMapper objectMapper = new ObjectMapper();

    public WxBizDataCrypt(String appId, String sessionKey) {
        this.appId = appId;
        this.sessionKey = sessionKey;
    }

    /**
     * 解密微信用户数据
     *
     * @param encryptedData 加密数据
     * @param iv            加密算法的初始向量
     * @return 解密后的用户数据
     */
    @SuppressWarnings("unchecked")
    public Map<String, Object> decryptData(String encryptedData, String iv) {
        try {
            // Base64解码
            byte[] dataByte = Base64.decodeBase64(encryptedData);
            byte[] keyByte = Base64.decodeBase64(sessionKey);
            byte[] ivByte = Base64.decodeBase64(iv);

            // 使用AES-128-CBC进行解密
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec keySpec = new SecretKeySpec(keyByte, "AES");
            IvParameterSpec ivSpec = new IvParameterSpec(ivByte);
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);

            byte[] resultByte = cipher.doFinal(dataByte);
            if (resultByte.length == 0) {
                return null;
            }

            String result = new String(resultByte, StandardCharsets.UTF_8);
            Map<String, Object> userInfo = objectMapper.readValue(result, Map.class);

            // 校验数据来源
            Map<String, String> watermark = (Map<String, String>) userInfo.get("watermark");
            if (watermark != null && appId.equals(watermark.get("appid"))) {
                return userInfo;
            }

            return null;
        } catch (Exception e) {
            log.error("微信数据解密失败", e);
            return null;
        }
    }
}